//
//  WCTFriendService.m
//  WeChatTool
//
//  Created by TerryChe on 2016/12/5.
//  Copyright © 2016年 TerryChe. All rights reserved.
//

#import "WCTWCDBContactService.h"
#import "WCTFriend.h"
#import "WCTChatroom.h"
#import "WCTConfig.h"

#include <sys/types.h>
#include <sys/stat.h>

@interface WCTWCDBContactService()<NSXMLParserDelegate>

@property (nonatomic, strong) NSString* path;
@property (nonatomic, strong) WCTFriend* me;
@property (nonatomic, strong) NSString* filePath;

@property (nonatomic, strong) NSMutableDictionary* xmlDic;
@property (nonatomic, strong) NSString* xmlKey;
@property (nonatomic, strong) NSString* xmlValue;
@property (nonatomic, assign) BOOL isXMLDisplayName;

@end

@implementation WCTWCDBContactService

-(instancetype)initWith:(NSString *)path AndME:(WCTFriend *)me AndFilePath:(NSString *)filePath{
    if(self == [super init])
    {
        self.path = path;
        self.me = me;
        self.filePath = filePath;
        
        //初始化cacheFriend
        NSString *friendPlistPath = [self.filePath stringByAppendingPathComponent:str_wct_friend];
        if ([[NSFileManager defaultManager] fileExistsAtPath:friendPlistPath]) {
            if (WCTConfig.sharedInstance.cacheFriend.count == 0) {
                NSDictionary *tempDic = [NSDictionary dictionaryWithContentsOfFile:friendPlistPath];
                if (tempDic != nil) {
                    [WCTConfig.sharedInstance.cacheFriend setDictionary:tempDic];
                }
            }
        }
        else {//文件不存在就把缓存去掉，实现重传功能
            [WCTConfig.sharedInstance.cacheFriend removeAllObjects];
        }
        
        //初始化cacheChatRoom
        NSString *chatroomPlistPath = [self.filePath stringByAppendingPathComponent:str_wct_chatroom];
        if ([[NSFileManager defaultManager] fileExistsAtPath:chatroomPlistPath]) {
            if (WCTConfig.sharedInstance.cacheChatRoom.count == 0) {
                NSMutableArray *tempArray = [NSMutableArray arrayWithContentsOfFile:chatroomPlistPath];
                if (tempArray != nil) {
                    [WCTConfig.sharedInstance.cacheChatRoom setArray:tempArray];
                }
            }
        }
        else {
            [WCTConfig.sharedInstance.cacheChatRoom removeAllObjects];
        }
    }
    
    return self;
}

//处理FriendTable
-(void)handleFriendData {//:(DBHelper2 *)db
    NSString* dbPath = [self.path stringByAppendingPathComponent:str_db_wcdb_contact];
    if (![[NSFileManager defaultManager] fileExistsAtPath:dbPath]) {
        log(@"数据库不存在：%@", dbPath);
        return;
    }
    
    log(@"DBPath ==== %@", dbPath)
    FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
    [db open];
    NSArray *table = [db syncExecuteQuery:@"select * from Friend"];
    [db close];
    
    NSArray* wct_filter_friend = @[@"filehelper", @"qqmail", @"qqsync", @"floatbottle", @"shakeapp", @"lbsapp", @"medianote", @"newsapp", @"facebookapp", @"qqfriend", @"masssendapp", @"feedsapp", @"qmessage", @"voipapp", @"officialaccounts", @"voicevoipapp", @"voiceinputapp", @"googlecontact", @"linkedinplugin", @"notifymessage", @"tmessage", @"fmessage", @"blogapp", @"brandsessionholder", @"notification_messages", @"iwatchholder", @"brandsessionholder_weapp", @"weixin", @"appbrandcustomerservicemsg"];
    
    NSMutableArray *friendArr = [NSMutableArray arrayWithCapacity: [WCTConfig sharedInstance].batchCount];
    NSMutableArray *chatroomArr = [NSMutableArray arrayWithCapacity: [WCTConfig sharedInstance].batchCount];
    NSMutableDictionary *tempAllFriends = [NSMutableDictionary dictionaryWithCapacity:[WCTConfig sharedInstance].batchCount];
    
    for (NSDictionary* row in table) {
        NSString *userName = row[@"userName"];
        //原始微信号为空
        if (userName == nil || [userName  isEqual: @""]) {
            continue;
        }
        
        //gh_ 公众号，订阅号
        if ([userName hasPrefix:@"gh_"] || [userName hasPrefix:@"fake_"] || [userName hasSuffix:@"@app"] || [userName hasSuffix:@"@qqim"] || [wct_filter_friend containsObject:userName]) {
//            NSLog(@"%@", row);
            continue;
        }
        
        //过滤已知应用
        if ([row[@"type"] intValue] %2 == 0 && ![userName hasSuffix:@"@chatroom"]) {
            continue;
        }
        
        WCTFriend *friend = [WCTFriend WCTFriendByWenober:userName Name:@"" Photo:@"" Remark:@"" Type:[row[@"type"] integerValue] Uwenober:@"" Label:@""];
        
        //基本信息
        NSData* data = nil;
        if (row[@"dbContactRemark"] == [NSNull null]) {
            log(@"userName:%@ dbContactRemark 解释失败\n%@", row[@"userName"], row[@"dbContactRemark"]);
            continue;
        }
        
        if ([row[@"dbContactRemark"] isKindOfClass:[NSString class]]) {
            data = [row[@"dbContactRemark"] dataUsingEncoding:NSUTF8StringEncoding];
        }
        else{
            data = row[@"dbContactRemark"];
        }
        NSArray* arr = [self getRemarkDataBy:data];
        
        if (arr == nil || arr.count == 0) {
            log(@"userName:%@ dbContactRemark 解释失败\n%@", row[@"userName"], row[@"dbContactRemark"]);
            continue;
        }
        
        friend.name = arr.count >= 1 ? arr[0] : @"";
        if(arr.count >= 3){
            friend.uwenober = arr[1];
            friend.remark = arr[2];
        }
        else if(arr.count >= 2){
            friend.remark = arr[1];
        }
        if (arr.count >= 8) {
            friend.label = arr[7];
        }
        
        //头像
        if (row[@"dbContactHeadImage"] != [NSNull null]) {
            if ([row[@"dbContactRemark"] isKindOfClass:[NSString class]]) {
                data = [row[@"dbContactHeadImage"] dataUsingEncoding:NSUTF8StringEncoding];
            }
            else{
                data = row[@"dbContactHeadImage"];
            }
            
            friend.photo = [self getPhotoBy:data];//[[NSData alloc] initWithData:row[@"dbContactHeadImage"]]
        }
        
        //检查是否群
        if ([friend.wenober hasSuffix:@"@chatroom"]) {
            //不存在就发送到服务器
            if (![WCTConfig.sharedInstance.cacheChatRoom containsObject:friend.wenober]) {
                NSData *chatroowData = [[NSData alloc] initWithData:row[@"dbContactChatroom"]];
                
                [self getChatroowBy:chatroowData];
                
                if (self.xmlDic != nil && self.xmlDic.count > 0) {
                    NSString *memberList = @"";
                    NSString *displayName = @"";
                    
                    for (NSString *key in [self.xmlDic allKeys]) {
                        memberList = [memberList stringByAppendingString:[NSString stringWithFormat:@"%@;", key]];
                        
                        for (NSDictionary* row in table) {
                            if ([row[@"userName"] isEqualToString:key]) {
                                NSData* data = nil;
                                if (row[@"dbContactRemark"] == [NSNull null]) {
                                    log(@"userName:%@ dbContactRemark 解释失败\n%@", row[@"userName"], row[@"dbContactRemark"]);
                                    continue;
                                }
                                
                                if ([row[@"dbContactRemark"] isKindOfClass:[NSString class]]) {
                                    data = [row[@"dbContactRemark"] dataUsingEncoding:NSUTF8StringEncoding];
                                }
                                else{
                                    data = row[@"dbContactRemark"];
                                }
                                NSArray* arr = [self getRemarkDataBy:data];
                                
                                if (arr == nil || arr.count == 0) {
                                    log(@"userName:%@ dbContactRemark 解释失败\n%@", row[@"userName"], row[@"dbContactRemark"]);
                                    continue;
                                }
                                
                                NSString *name = [NSString stringWithFormat:@"%@、", arr.count >= 1 ? arr[0] : @""];
//                                _cacheChatRoomMember[key] = name;
                                displayName = [displayName stringByAppendingString:name];
                            }
                        }
                    }
                    
                    if (memberList.length > 0) {
                        memberList = [memberList substringToIndex:memberList.length - 1];
                    }
                    
                    if (displayName.length > 0) {
                        displayName = [displayName substringToIndex:displayName.length - 1];
                    }
                    
//                    for (NSString *value in [self.xmlDic allValues]) {
//                        displayName = [displayName stringByAppendingString:[NSString stringWithFormat:@"%@,", value]];
//                    }
//                    displayName = [displayName substringToIndex:displayName.length - 1];
                    
                    WCTChatroom *chatroom = [WCTChatroom WCTChatroomByName:friend.wenober MemberList:memberList DisplayName:displayName SelfDisplayName:[self.xmlDic objectForKey:self.me.wenober] IsShowname:0 Nober:[self.me getWeChatNo]];
                    
                    [chatroomArr addObject:chatroom];
                    
                    //群名称为空时，显示用户名
                    if ([friend.name isEqualToString:@""]) {
                        friend.name = displayName.length > 20 ? [displayName substringToIndex:20] : displayName;
                    }
                }
            }
        }

        //是否有cache
        NSDictionary *cacheDic = [WCTConfig.sharedInstance.cacheFriend objectForKey:friend.wenober];
        if (cacheDic == nil || cacheDic.count == 0) {
            if  ([friend checkIsDel] == 0){
                [friendArr addObject:friend];
            }
        }
        else{
            //检查是否更新了
            WCTFriend *cacheData = [WCTFriend WCTFriendByDic:cacheDic];
            if (![friend isEqual:cacheData]) {
                [friendArr addObject:friend];
            }
        }
        
        [tempAllFriends setObject:friend forKey:friend.wenober];
    }
    
    NSMutableArray *deleteArr = [NSMutableArray arrayWithCapacity:[WCTConfig sharedInstance].batchCount];
    for (NSString *key in [WCTConfig.sharedInstance.cacheFriend allKeys]) {
        WCTFriend *temp = [tempAllFriends objectForKey:key];
        if (temp == nil) {
            WCTFriend *delectFriend = [WCTFriend WCTFriendByDic:[WCTConfig.sharedInstance.cacheFriend objectForKey:key]];
            delectFriend.type = 11;//令isDel = 1
            [deleteArr addObject:delectFriend];
        }
    }

    if (deleteArr.count > 0) {
        log(@"删除好友总数：%lu", (unsigned long)deleteArr.count);
        [self uploadFriendBy:deleteArr IsDelete:true];
    }

    log(@"好友资料 需要上传总数：%lu", (unsigned long)friendArr.count);
    for (int i=0; i<friendArr.count; i=i+[WCTConfig sharedInstance].batchCount) {
        NSRange range;
        if (i + [WCTConfig sharedInstance].batchCount < friendArr.count) {
            range = NSMakeRange(i, [WCTConfig sharedInstance].batchCount);
        }
        else{
            range = NSMakeRange(i, friendArr.count - i);
        }

        NSArray *arr = [friendArr subarrayWithRange:range];

        log(@"range location:%lu length:%lu", (unsigned long)range.location, (unsigned long)range.length);
        [self uploadFriendBy:arr IsDelete:false];
    }

    log(@"群资料 需要上传总数：%lu", (unsigned long)chatroomArr.count);
    for (int i=0; i<chatroomArr.count; i=i+[WCTConfig sharedInstance].batchCount) {
        NSRange range;
        if (i + [WCTConfig sharedInstance].batchCount < chatroomArr.count) {
            range = NSMakeRange(i, [WCTConfig sharedInstance].batchCount);
        }
        else{
            range = NSMakeRange(i, chatroomArr.count - i);
        }

        NSArray *arr = [chatroomArr subarrayWithRange:range];

        log(@"range location:%lu length:%lu", (unsigned long)range.location, (unsigned long)range.length);
        [self uploadChatroomBy:arr];
    }
}

//解析dbContactRemark
-(NSArray*)getRemarkDataBy:(NSData *)data{
    Byte *testByte = (Byte *)[data bytes];
    
    NSMutableArray* arr = [NSMutableArray arrayWithCapacity:[WCTConfig sharedInstance].batchCount];
    int len = 0;
    int index = 0;
    while (true) {
        index++;
        len = testByte[index];
        index++;
        
        if (index + len > [data length]) {
            break;
        }
        
        NSString* str = [[NSString alloc]initWithData:[data subdataWithRange:NSMakeRange(index, len)] encoding:NSUTF8StringEncoding];
        if (str != nil) {
            [arr addObject:str];
        }
        
        index += len;
    }
    
    return arr;
}

//解析dbContactHeadImage
-(NSString *)getPhotoBy:(NSData *)data{
    if (data.length <= 8) {
        return @"";
    }
    
    int begin = 0;
    int end = 0;
    
    Byte *byteData = (Byte *)[data bytes];
    for(int i=0;i<[data length];i++){
        if (byteData[i] == 104 && begin == 0) {//104 = "h"
            begin = i;
        }
        
        if (byteData[i] == 26 && end == 0) {//26 = "结束"
            end = i;
        }
    }
    
    if (begin > 0 && end > 0) {
        int len = end - begin;
        NSData* tempData = [data subdataWithRange:NSMakeRange(begin, len)];
        NSString* str = [[NSString alloc]initWithData:tempData encoding:NSASCIIStringEncoding];
        
        return str;
    }
    
    return @"";
}

//解析dbContactChatroom
-(void)getChatroowBy:(NSData *)data{
    NSMutableArray *arr = [NSMutableArray arrayWithCapacity:[WCTConfig sharedInstance].batchCount];
    Byte *byteData = (Byte *)[data bytes];
    for(int i=0;i<[data length];i++){
        if (byteData[i] == 60 || byteData[i] == 62) {//60 = "<" 62 = ">"
            [arr addObject:@(i)];
        }
    }
    
    if (arr.count >= 2) {
        int begin = [arr.firstObject intValue];
        int len = [arr.lastObject intValue] - begin + 1;

        NSData *tempData = [data subdataWithRange:NSMakeRange(begin, len)];
        
        // 2. XML解析
        // 1) 解析器
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:tempData];
        // 2) 设置代理
        parser.delegate = self;
        
        // 3）开始解析
        [parser parse];
    }
}

-(void)uploadFriendBy:(NSArray *)array IsDelete:(BOOL)isDelete{
    if (array == nil || array.count == 0) {
        return;
    }
    
    NSMutableDictionary *tempDic = [NSMutableDictionary dictionaryWithCapacity:[WCTConfig sharedInstance].batchCount];
    NSMutableArray *friendList = [NSMutableArray arrayWithCapacity:[WCTConfig sharedInstance].batchCount];
    for (WCTFriend* friend in array) {
        NSDictionary *temp = [friend convertToDic];
        
        if (temp == nil) {
            continue;
        }
        
        [friendList addObject:temp];
        [tempDic setObject:temp forKey:friend.wenober];
    }
    
    if (friendList.count == 0) {
        return;
    }
    
    NSMutableDictionary *dicParams = [NSMutableDictionary dictionaryWithCapacity:[WCTConfig sharedInstance].batchCount];
    [dicParams setObject:[self.me getWeChatNo] forKey:@"wenober"];
    [dicParams setObject:friendList forKey:@"list"];
    
    NSString* url = [NSString stringWithFormat:@"%@/api/weichart?format=json&access_token=%@", [WCTConfig sharedInstance].address, [WCTConfig sharedInstance].token];
    OPHRequest* request = [OPHRequest jsonReqeust:url type:OPH_HTTP_POST params:dicParams];
    OPHResponse* response = [[OPHNetwork sharedInstance] syncRequest:request];
    
    if ([response isRequestOk]) {
        OPHJsonStatusResult* jsonResult = [response expectedJsonStatusResultObject];
        
        log(@"好友资料上传 %@", [jsonResult description]);
        
        if ([jsonResult isResultSuccess]) {
            //Key相同覆盖原本的Value
            [self cacheFriend:tempDic IsDelete:isDelete];
        }
        else{
            [[OPHNetwork sharedInstance] throwNetworkException:[NSString stringWithFormat:@"好友资料上传 %@", [jsonResult description]]];
        }
    }
}

-(void)cacheFriend:(NSDictionary *)newData IsDelete:(BOOL)isDelete{
//    if (isDelete) {
//        for (NSString *key in [newData allKeys]) {
//            [WCTConfig.sharedInstance.cacheFriend removeObjectForKey:key];
//        }
//    }
//    else {
//        //Key相同覆盖原本的Value
//        [WCTConfig.sharedInstance.cacheFriend addEntriesFromDictionary:newData];
//    }
    
    for (NSString *key in [newData allKeys]) {
        if (isDelete) {
            [WCTConfig.sharedInstance.cacheFriend removeObjectForKey:key];
        }
        else {
            [WCTConfig.sharedInstance.cacheFriend setObject:[newData objectForKey:key] forKey:key];
        }
    }

    //写入plist
    NSString *filePath = [self.filePath stringByAppendingPathComponent:str_wct_friend];
    BOOL succeed =  [WCTConfig.sharedInstance.cacheFriend writeToFile:filePath atomically:YES];
    log(@"cacheFriend: %d====Count：%d", succeed, (int)WCTConfig.sharedInstance.cacheFriend.count);
}

-(void)uploadChatroomBy:(NSArray *)array{
    if (array == nil || array.count == 0) {
        return;
    }
    
    NSMutableArray *tempDic = [NSMutableArray arrayWithCapacity:[WCTConfig sharedInstance].batchCount];
    NSMutableArray *friendList = [NSMutableArray arrayWithCapacity:[WCTConfig sharedInstance].batchCount];
    for (WCTChatroom* chatroom in array) {
        NSDictionary *temp = [chatroom convertToDic];
        if (temp == nil) {
            continue;
        }
        [friendList addObject:temp];
        [tempDic addObject:chatroom.name];
    }
    
    if (friendList.count == 0) {
        return;
    }
    
    NSMutableDictionary *dicParams = [NSMutableDictionary dictionaryWithCapacity:[WCTConfig sharedInstance].batchCount];
    [dicParams setObject:friendList forKey:@"list"];
    
    NSString* url = [NSString stringWithFormat:@"%@/api/weichart/Postchatroom?format=json&access_token=%@", [WCTConfig sharedInstance].address, [WCTConfig sharedInstance].token];
    OPHRequest* request = [OPHRequest jsonReqeust:url type:OPH_HTTP_POST params:dicParams];
    OPHResponse* response = [[OPHNetwork sharedInstance] syncRequest:request];
    
    if ([response isRequestOk]) {
        OPHJsonStatusResult* jsonResult = [response expectedJsonStatusResultObject];
        
        log(@"群资料上传 %@", [jsonResult description]);
        
        if ([jsonResult isResultSuccess]) {
            //Key相同覆盖原本的Value
            [self cacheChatRoom:tempDic];
        }
        else{
            [[OPHNetwork sharedInstance] throwNetworkException:[NSString stringWithFormat:@"群资料上传 %@", [jsonResult description]]];
        }
    }
}

-(void)cacheChatRoom:(NSArray *)newData{
    //Key相同覆盖原本的Value
    [WCTConfig.sharedInstance.cacheChatRoom addObjectsFromArray:newData];
    
    //写入plist
    NSString *filePath = [self.filePath stringByAppendingPathComponent:str_wct_chatroom];
    BOOL succeed =  [WCTConfig.sharedInstance.cacheChatRoom writeToFile:filePath atomically:YES];
    log(@"cacheChatRoom: %d====Count：%d", succeed, (int)WCTConfig.sharedInstance.cacheChatRoom.count);
}

#pragma mark - XML解析方法
// 1. 开始解析文档，在这里做初始化工作
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
//    NSLog(@"开始解析文档");
    
    self.xmlDic = [NSMutableDictionary dictionaryWithCapacity:[WCTConfig sharedInstance].batchCount];
    self.xmlKey = @"";
    self.xmlValue = @"";
}

// 2.3.4会循环执行，一直到XML文档解析完毕
// 2. 解析一个节点
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//    NSLog(@"节点开始 %@ %@", elementName, attributeDict);
    
    if ([elementName isEqualToString:@"Member"]) {
        self.xmlKey = [attributeDict objectForKey:@"userName"];
    }
    
    if ([elementName isEqualToString:@"DisplayName"]) {
        self.isXMLDisplayName = true;
    }
}

// 3. 查找节点内容，可能会多次
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//    NSLog(@"开始查找内容 %@", string);
    
    if (self.isXMLDisplayName) {
        self.xmlValue = string;
    }
}

// 4. 节点完成
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
//    NSLog(@"节点完成 %@ %@", elementName, qName);
    
    if ([elementName isEqualToString:@"Member"]) {
        [self.xmlDic setObject:self.xmlValue forKey:self.xmlKey];
        
        self.xmlKey = @"";
        self.xmlValue = @"";
    }
    
    if ([elementName isEqualToString:@"DisplayName"]) {
        self.isXMLDisplayName = false;
    }
}

// 5. 解析完成，做收尾工作
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//    NSLog(@"解析完成");
}

// 6. 解析出错，清理中间数据
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
//    NSLog(@"%@", parseError.localizedDescription);
}

- (void)handleLabel{
    log(@"获取Label文件");
    NSString* labelPath = [self.path stringByAppendingPathComponent:str_contactlabel];
    if (![[NSFileManager defaultManager] fileExistsAtPath:labelPath]) {
        log(@"没找到contactlabel.list：%@", labelPath);
        return;
    }
    
    NSMutableDictionary* data = [NSMutableDictionary dictionaryWithContentsOfFile:labelPath];
    if (data == nil) {
        return;
    }
    
    NSMutableArray* arrObj = [data objectForKey:@"$objects"];
    if (arrObj == nil) {
        return;
    }
    
    NSMutableArray* labelArr = [NSMutableArray arrayWithCapacity:[WCTConfig sharedInstance].batchCount];
    
    for (int i=0; i<arrObj.count; i++) {
        if ([arrObj[i] isKindOfClass:[NSString class]] && i > 0 && [arrObj[i - 1] isKindOfClass:[NSMutableDictionary class]]) {
            NSString* labelName = arrObj[i];
            
            NSString* labelID = [arrObj[i - 1][@"m_uiID"] stringValue];
            
            WCTFriend *friend = [WCTFriend WCTFriendByWenober:labelID Name:labelName Photo:@"" Remark:@"" Type:WCT_LabelType Uwenober:@"" Label:@""];
            
            [labelArr addObject:friend];
        }
    }
    
    log(@"Label上传数：%lu", (unsigned long)labelArr.count);
    [self uploadFriendBy:labelArr IsDelete:false];
}

@end
